﻿// ------------------------------------------------------------------------------------
//      Copyright (c) uhavemyword@gmail.com. All rights reserved.
//      Created by Ben at 2/26/2013 9:14:38 PM
// ------------------------------------------------------------------------------------

namespace CP.NLayer.Service.Services
{
    using CP.NLayer.Data;
    using CP.NLayer.Models.Business;
    using CP.NLayer.Models.Entities;
    using CP.NLayer.Service.Contracts;
    using Microsoft.Practices.Unity;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel;

    [ErrorHandlingBehavior]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class RoleEditModelService : IRoleEditModelService
    {
        public RoleEditModel Create()
        {
            var service = DependencyInjection.Container.Resolve<IPermissionService>();
            return new RoleEditModel
            {
                Role = new Role(),
                PermissionList = service.GetCheckList()
            };
        }

        public RoleEditModel GetById(object id)
        {
            var worker = DependencyInjection.Container.Resolve<IUnitOfWork>();
            var role = worker.GetRepository<Role>().Table.Where(x => x.Id == (string)id).Include(x => x.Permissions).FirstOrDefault();
            if (role == null)
            {
                return null;
            }
            var model = new RoleEditModel();
            model.Role = role;
            var permissionService = DependencyInjection.Container.Resolve<IPermissionService>();
            model.PermissionList = permissionService.GetCheckList();
            model.PermissionList.ToList().ForEach(x => x.Checked = model.Role.Permissions.Where(y => y.Name == x.Text).Count() == 1);
            return model;
        }

        public RoleEditModel Insert(RoleEditModel model)
        {
            var worker = DependencyInjection.Container.Resolve<IUnitOfWork>(); // use same worker for following service
            var service = DependencyInjection.Container.Resolve<IRoleService>(new ParameterOverride("worker", worker));
            var permissionService = DependencyInjection.Container.Resolve<IPermissionService>(new ParameterOverride("worker", worker));
            var role = service.Insert(model.Role);
            var permissions = permissionService.GetAll();
            foreach (var p in permissions)
            {
                if (model.PermissionList.Where(x => x.Text == p.Name && x.Checked == true).Count() == 1)
                {
                    role.Permissions.Add(p);
                }
            }
            service.Update(role);
            return new RoleEditModel
            {
                Role = role,
                PermissionList = service.GetCheckList()
            };
        }

        public void Update(RoleEditModel model)
        {
            var worker = DependencyInjection.Container.Resolve<IUnitOfWork>(); // use same worker for following service
            var service = DependencyInjection.Container.Resolve<IRoleService>(new ParameterOverride("worker", worker));
            var permissionService = DependencyInjection.Container.Resolve<IPermissionService>(new ParameterOverride("worker", worker));

            var role = model.Role;
            service.Update(role); // update fields
            role = worker.GetRepository<Role>().Table.Where(x => x.Id == role.Id).Include(x => x.Permissions).FirstOrDefault();
            var permissions = permissionService.GetAll();
            foreach (var p in permissions)
            {
                if (model.PermissionList.Where(x => x.Text == p.Name && x.Checked == true).Count() == 1)
                {
                    if (!role.Permissions.Any(x => x.Id == p.Id))
                    {
                        role.Permissions.Add(p);
                    }
                }
                else
                {
                    if (role.Permissions.Any(x => x.Id == p.Id))
                    {
                        role.Permissions.Remove(p);
                    }
                }
            }

            service.Update(role); // update relationship
        }

        public void Delete(RoleEditModel entity)
        {
            var service = DependencyInjection.Container.Resolve<IRoleService>();
            service.Delete(entity.Role);
        }

        public void DeleteById(object id)
        {
            var service = DependencyInjection.Container.Resolve<IRoleService>();
            service.DeleteById(id);
        }
    }
}
